/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.security.core.spring.authentication;

import io.iec.edp.caf.security.core.UserDetails;
import io.iec.edp.caf.security.core.authentication.CafSecurityAuthentication;
import io.iec.edp.caf.security.core.authentication.CafSecurityCredentials;
import io.iec.edp.caf.security.core.authentication.CafSecurityPrincipal;
import io.iec.edp.caf.core.session.SessionReservedKeyCollection;
import io.iec.edp.caf.core.session.SessionType;
import io.iec.edp.caf.core.session.WebSession;
import lombok.Getter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

import java.time.ZonedDateTime;
import java.util.Collection;

import static org.springframework.http.HttpHeaders.ORIGIN;

/**
 * This is {@link CAFSpringSecurityAuthentication}.
 *
 * @author yisiqi
 * @since 1.0.0
 */
public class CAFSpringSecurityAuthentication extends WebSession implements Authentication {
    private static final String CAF_LANG_PARAM_NAME = "language";
    @Getter
    private final CafSecurityCredentials credentials;
    @Getter
    private final CafSecurityPrincipal principal;
    @Getter
    private  UserDetails userDetails;
    @Getter
    private final boolean authenticated;


    public CAFSpringSecurityAuthentication(CafSecuritySpringAuthentication<?> springAuthn, CafSecurityAuthentication cafAuthn) {
        super(
                springAuthn.getRequest().getSession().getId(),
                ZonedDateTime.now(),
                cafAuthn.getUserDetails().getCurrentTenantId().map(Integer::parseInt).orElse(null),
                cafAuthn.getUserDetails().getId(),
                cafAuthn.getPrincipal().getId(),
                cafAuthn.getUserDetails().getFullName().orElse(null),
                springAuthn.getRequest().getRemoteAddr(),
                springAuthn.getRequest().getRemotePort(),
                springAuthn.getRequest().getHeader(ORIGIN),
                springAuthn.getRequest().getLocalAddr(),
                springAuthn.getRequest().getLocalPort(),
                springAuthn.getRequest().getContextPath(),
                cafAuthn.getUserDetails().getUser().getCustomizedLocaleString().orElse("zh-CHS"),
                ("Computer".equals(springAuthn.getRequest().getDeviceType()) ? SessionType.web
                        : ("Mobile".equals(springAuthn.getRequest().getDeviceType())? SessionType.mobile
                        : SessionType.web)
                )
        );
        this.authenticated = cafAuthn.isAuthenticated();
        this.credentials = cafAuthn.getCredentials();
        this.principal = cafAuthn.getPrincipal();
        this.userDetails = cafAuthn.getUserDetails();
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    public Object getDetails() {
        return userDetails;
    }

    public void setDetails(UserDetails userDetails){
        this.userDetails=userDetails;
    }

    @Override
    public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
    }

    @Override
    public String getName() {
        return this.getUserName();
    }

    @Override
    public String getSysOrgId() {
        if (this.userDetails != null)
            return this.userDetails.getUser().getExternalAttributeAsString(SessionReservedKeyCollection.SysOrgId).orElse(null);
        return null;
    }

    @Override
    public String getSysOrgCode() {
        if (this.userDetails != null)
            return this.userDetails.getUser().getExternalAttributeAsString(SessionReservedKeyCollection.SysOrgCode).orElse(null);
        return null;
    }

    @Override
    public String getSysOrgName() {
        if (this.userDetails != null)
            return this.userDetails.getUser().getExternalAttributeAsString(SessionReservedKeyCollection.SysOrgName).orElse(null);
        return null;
    }

    @Override
    public String getPhone() {
        if (this.userDetails != null)
            return this.userDetails.getPhone().orElse(null);
        return null;
    }
}
